#include "coutline.h"
#include <QDebug>
QList<QVector3D*> *MyData;
QRectF *MyRect;
QVector3D MyTr;

void print4bytes(const char *bytes);
int move_to(const FT_Vector *to, void *user);
int line_to(const FT_Vector *to, void *user);
int conic_to(const FT_Vector *control, const FT_Vector *to, void *user);
int cubic_to(const FT_Vector *control1,
             const FT_Vector *control2,
             const FT_Vector *to, void *user);

void appendVek(QVector3D *nv)
{
  if(MyData->isEmpty())
  {
    MyRect->setLeft(nv->x());
    MyRect->setTop(nv->y());
    MyRect->setRight(nv->x());
    MyRect->setBottom(nv->y());
  }
  else
  {
    if(nv->x() < MyRect->left()) MyRect->setLeft(nv->x());
    if(nv->y() < MyRect->top()) MyRect->setTop(nv->y());
    if(nv->x() > MyRect->right()) MyRect->setRight(nv->x());
    if(nv->y() > MyRect->bottom()) MyRect->setBottom(nv->y());
  }
  MyData->append(nv);
}

void print4bytes(const char *bytes)
{
   qDebug() << bytes[0] << bytes[1] << bytes[2] << bytes[3];
}

int move_to(const FT_Vector *to, void *user)
{
    print4bytes((char *) &(to->x));
    print4bytes((char *) &(to->y));
    QVector3D *nv = new  QVector3D(DOUBLE_FROM_26_6(to->x), -DOUBLE_FROM_26_6(to->y), 0);
    *nv += MyTr;
    qDebug() << "move_to" << *nv;
    appendVek(nv);
    return 0;
}

int line_to(const FT_Vector *to, void *user)
{
    qDebug() << "line_to\n" << DOUBLE_FROM_26_6(to->x) << DOUBLE_FROM_26_6(to->y);
    QVector3D *nv = new  QVector3D(DOUBLE_FROM_26_6(to->x), -DOUBLE_FROM_26_6(to->y), 1);
    *nv += MyTr;
    appendVek(nv);
    return 0;
}

int conic_to(const FT_Vector *control, const FT_Vector *to, void *user)
{
    qDebug() <<  "conic_to(c =" <<
        DOUBLE_FROM_26_6(control->x) << DOUBLE_FROM_26_6 (control->y) << " to:"
           << DOUBLE_FROM_26_6(to->x) << DOUBLE_FROM_26_6(to->y);
    QVector3D *nv = new  QVector3D(DOUBLE_FROM_26_6(to->x), -DOUBLE_FROM_26_6(to->y), 1);
    *nv += MyTr;
    appendVek(nv);
    return 0;
}

int cubic_to(const FT_Vector *control1, const FT_Vector *control2,
             const FT_Vector *to, void *user)
{
   qDebug() << "cubic_to(c1, c2, to)" <<
           DOUBLE_FROM_26_6(control1->x) << DOUBLE_FROM_26_6 (control1->y) <<
           DOUBLE_FROM_26_6(control2->x) << DOUBLE_FROM_26_6 (control2->y) <<
           DOUBLE_FROM_26_6(to->x), DOUBLE_FROM_26_6(to->y);
   QVector3D *nv = new  QVector3D(DOUBLE_FROM_26_6(to->x), -DOUBLE_FROM_26_6(to->y), 1);
   *nv += MyTr;
   appendVek(nv);
    return 0;
}

COutline::COutline()
{

}

void COutline::load(QString fontfile, QString text, QList<QVector3D*> *data, QRectF *rect)
{
  MyTr = QVector3D(0,0,0);
  MyRect = rect;
  MyData = data;
  MyData->clear();
  FT_Library  library;
  FT_Face     face;
  FT_UInt     glyph_index;
  FT_Outline *outline;
  FT_Init_FreeType(&library);
  FT_New_Face(library, fontfile.toUtf8(), 0, &face);
  FT_ULong charcode;
  FT_Outline_Funcs outline_funcs = { move_to, line_to, conic_to, cubic_to, 0, 0 };
  for(int i = 0; i < text.length(); i++)
  {
    charcode = text.at(i).toAscii();
    if(charcode == 10)
    {
      MyTr.setX(0);
      MyTr.setY(MyTr.y() - 12);
    }
    else
    {
      glyph_index = FT_Get_Char_Index(face, charcode);
      FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE);
      outline = &face->glyph->outline;
      printf("n_contours = %d\n", outline->n_contours);
      printf("n_points   = %d\n", outline->n_points);
      FT_Outline_Decompose(outline, &outline_funcs, NULL);
      FT_Pos *p;
      p = &face->glyph->metrics.horiAdvance;
      MyTr.setX(MyTr.x()+DOUBLE_FROM_26_6(*p));
    }
  }

  FT_Done_Face(face);
  FT_Done_FreeType(library);
  for(int i = 0; i < data->size(); i++)
  {
    QVector3D *v = data->at(i);
    v->setX(v->x() - rect->left());
    v->setY(v->y() - rect->top());
  }
}
